﻿module JsEngine

open JsEval
open JsTypes
open JsParser
open FParsec

type BuiltinNativeObject() =
    inherit NativeObject()

let builtins topFrame = [
    ("Object", Object(NativeFunction(topFrame,[],[], evalFunctionBody)))
    ]

let objectObjectPrototype = BuiltinNativeObject()

type JsEngine(predefined:(string*JsValue) list) =
    let _predefined = predefined
    let mutable _topEnv = createTopFrame predefined (Object(objectObjectPrototype))
    let _builtins = builtins _topEnv
    do 
        do _topEnv.record.addBindings _builtins
    member this.eval src = 
        match parseJs src with
        | Success(stmts,_,_) -> this.evalAstSafe stmts
        | Failure(msg,_,_) -> 
            // TODO: Log error
            Undefined
    member this.evalAstSafe stmts =
            try
                this.evalAst stmts
            with
                ex ->
                    // TODO: log error
                    Undefined        
    member this.evalAst stmts =
            let (Value(x)) = evalStmts stmts _topEnv
            x
    member this.invokeValue handler = 
        call handler [] _topEnv

